﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Revit;

namespace YArchitech.HVAC
{
	[Transaction(TransactionMode.Manual)]
	[Regeneration(RegenerationOption.Manual)]
	public class HYPipeConnectHSprinklersBranch : IExternalCommand
	{
		public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
		{
			Transaction transaction = null;
			Result result;
			try
			{
				if (commandData == null)
				{
					throw new System.ArgumentNullException("commandData", "is null");
				}
				UIDocument activeUIDocument = commandData.Application.ActiveUIDocument;
				Document document = activeUIDocument.Document;
				Selection selection = activeUIDocument.Selection;
				ISelectionFilter selectionFilter = new PipeSprinklersSelectionFilter();
				HYPipeConnect hypipeConnect = new HYPipeConnect();
				int num = 0;
				string text = "支管连接喷头";
				transaction = new Transaction(document, text);
				transaction.Start();
				for (;;)
				{
					SubTransaction subTransaction = new SubTransaction(document);
					try
					{
						try
						{
							if (num != 0)
							{
								RevitVersionFuncs.ClearSelection(selection);
							}
							num++;
							IList<Element> list = new List<Element>();
							IList<Element> list2 = new List<Element>();
							if (selection.GetElementIds().Any<ElementId>())
							{
								foreach (ElementId elementId in selection.GetElementIds())
								{
									list.Add(document.GetElementById(elementId));
								}
							}
							bool flag = true;
							double num2 = 0.0;
							double num3 = 100000.0;
							bool flag2 = false;
							bool flag3 = false;
							ConnectHelper connectHelper = new ConnectHelper();
							foreach (Element element in list)
							{
								if (-2008099 == element.Category.Id.IntegerValue)
								{
									list2.Add(element);
									if (connectHelper.GetYJKElementConnector(element).CoordinateSystem.BasisZ.IsAlmostEqualTo(new XYZ(0.0, 0.0, -1.0)))
									{
										double z = (element.Location as LocationPoint).Point.Z;
										if (z < num3)
										{
											num3 = z;
											flag3 = true;
										}
									}
									else
									{
										double z2 = (element.Location as LocationPoint).Point.Z;
										if (z2 > num2)
										{
											num2 = z2;
											flag2 = true;
										}
									}
									flag = false;
								}
							}
							RevitVersionFuncs.ClearSelection(selection);
							if (flag)
							{
								foreach (Element element2 in selection.PickElementsByRectangle(selectionFilter, "请框选喷头"))
								{
									list2.Add(element2);
									if (connectHelper.GetYJKElementConnector(element2).CoordinateSystem.BasisZ.IsAlmostEqualTo(new XYZ(0.0, 0.0, -1.0)))
									{
										double z = (element2.Location as LocationPoint).Point.Z;
										if (z < num3)
										{
											num3 = z;
											flag3 = true;
										}
									}
									else
									{
										double z2 = (element2.Location as LocationPoint).Point.Z;
										if (z2 > num2)
										{
											num2 = z2;
											flag2 = true;
										}
									}
								}
							}
							subTransaction.Start();
							if (list2.Count >= 1)
							{
								if (list2.Count < 2)
								{
									MessageBox.Show("喷头选择不能少于2个", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
								}
								else
								{
									double num4 = 0.0;
									XYZ xyz = null;
									XYZ xyz2 = null;
									for (int i = 0; i < list2.Count - 1; i++)
									{
										for (int j = i + 1; j < list2.Count; j++)
										{
											double num5 = YJKRevitTools.DistanceTwoXYZ(YJKRevitTools.GetLoctaionPoint(list2[i]), YJKRevitTools.GetLoctaionPoint(list2[j]));
											if (num5 > num4)
											{
												num4 = num5;
												xyz = YJKRevitTools.GetLoctaionPoint(list2[i]);
												xyz2 = YJKRevitTools.GetLoctaionPoint(list2[j]);
											}
										}
									}
									if (flag2 && flag3)
									{
										if (num2 + 1.5 >= num3 - 1.5)
										{
											throw new Exception("喷头的喷淋方向不统一，不能画出一根合适的水管进行连接");
										}
										num2 = (num2 + num3) / 2.0;
									}
									else if (flag2)
									{
										num2 += 1.5;
									}
									else if (flag3)
									{
										num2 = num3 - 1.5;
									}
									XYZ start = new XYZ(xyz.X, xyz.Y, num2);
									XYZ end = new XYZ(xyz2.X, xyz2.Y, num2);
									PipingSystemType pipingSystemType = null;
									PipeType pipeType = null;
									List<Element> elementByClass = YJKElementFilter.GetElementByClass(typeof(PipingSystemType), document);
									List<Element> elementByClass2 = YJKElementFilter.GetElementByClass(typeof(PipeType), document);
									using (List<Element>.Enumerator enumerator3 = elementByClass.GetEnumerator())
									{
										if (enumerator3.MoveNext())
										{
											pipingSystemType = (enumerator3.Current as PipingSystemType);
										}
									}
									using (List<Element>.Enumerator enumerator3 = elementByClass2.GetEnumerator())
									{
										if (enumerator3.MoveNext())
										{
											pipeType = (enumerator3.Current as PipeType);
										}
									}
									Pipe pipe = document.CreatHYPipe(pipingSystemType, pipeType, document.ActiveView.GenLevel, start, end, 0.32808398950131235);
									YJKPiping<Pipe> hypiping = new YJKPiping<Pipe>(pipe);
									hypiping.SetDiameter(100.0);
									ElementId level = list2[0].get_Parameter(BuiltInParameter.FAMILY_LEVEL_PARAM).AsElementId();
									hypiping.SetLevel(level);
									if (!hypipeConnect.PipeConnectHSprinklersByRectangle(pipe, list2, this.GetPipeConnectType(pipe)))
									{
										MessageBox.Show("连接失败", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
									}
								}
							}
							document.Regenerate();
							subTransaction.Commit();
						}
						catch (Autodesk.Revit.Exceptions.OperationCanceledException)
						{
							return Autodesk.Revit.UI.Result.Succeeded;
						}
						catch (Exception ex)
						{
							MessageBox.Show(ex.Message, "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Hand);
							break;
						}
						continue;
					}
					finally
					{
						if (subTransaction != null)
						{
							TransactionStatus status = subTransaction.GetStatus();
							if ((int)status == 1)
							{
								subTransaction.Commit();
							}
							else if ((int)status == 5)
							{
								subTransaction.RollBack();
							}
						}
					}
					break;
				}
				transaction.Commit();
				result = Autodesk.Revit.UI.Result.Succeeded;
			}
			catch (Autodesk.Revit.Exceptions.OperationCanceledException)
			{
				result = Autodesk.Revit.UI.Result.Succeeded;
			}
			catch (Exception ex2)
			{
				message = ex2.Message;
				result = Autodesk.Revit.UI.Result.Failed;
			}
			finally
			{
				TransactionStatus status2 = transaction.GetStatus();
				if ((int)status2 == 1)
				{
					transaction.Commit();
				}
				else if ((int)status2 == 5)
				{
					transaction.RollBack();
				}
			}
			return result;
		}

		private int GetPipeConnectType(Pipe pipe)
		{
			return pipe.PipeType.get_Parameter(BuiltInParameter.RBS_CURVETYPE_PREFERRED_BRANCH_PARAM).AsInteger();
		}
	}
}
